using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
using System.Xml;
using System.Threading;

namespace cb0tServer
{
    class AutoLogin
    {
        private static Mutex mutex = new Mutex();
        private static List<AutoLoginItem> login_items = new List<AutoLoginItem>();

        public static bool IsHost(IPAddress ip)
        {
            byte[] buff = ip.GetAddressBytes();

            switch (buff[0])
            {
                case 192:
                    if (buff[1] == 168) return true;
                    break;

                case 127:
                    return true;

                case 10:
                    if (buff[1] == 0) return true;
                    break;

                default:
                    break;
            }

            if (ip.Equals(CoreSettings.room_external_ip)) return true;

            return false;
        }

        public static bool IsCoHost(IPAddress ip)
        {
            return ip.Equals(CoreSettings.additional_host);
        }

        public static void AddAutoLogin(UserObject userobj, int level)
        {
            foreach (AutoLoginItem a in login_items)
            {
                if (userobj.physical_ip.Equals(a.ip) ||
                    (userobj.guid.Equals(a.guid) && a.ip.GetAddressBytes()[0] == 
                    userobj.physical_ip.GetAddressBytes()[0]))
                {
                    a.name = userobj.name;
                    a.ip = userobj.physical_ip;
                    a.guid = userobj.guid;
                    a.level = level;
                    SaveAutoLogins();
                    return;
                }
            }

            AutoLoginItem al = new AutoLoginItem();
            al.name = userobj.name;
            al.ip = userobj.physical_ip;
            al.guid = userobj.guid;
            al.level = level;
            login_items.Add(al);
            SaveAutoLogins();
        }

        public static String RemoveAutoLogin(ushort _id)
        {
            if (_id < login_items.Count)
            {
                String str = login_items[_id].name;
                login_items.RemoveAt(_id);
                SaveAutoLogins();
                return str;
            }

            return null;
        }

        public static AutoLoginItem[] GetAutoLogins()
        {
            if (login_items.Count > 0)
            {
                return login_items.ToArray();
            }

            return null;
        }

        public static int IsAdmin(UserObject userobj)
        {
            foreach (AutoLoginItem a in login_items)
            {
                if (userobj.physical_ip.Equals(a.ip) ||
                    (userobj.guid.Equals(a.guid) && a.ip.GetAddressBytes()[0] ==
                    userobj.physical_ip.GetAddressBytes()[0]))
                {
                    return a.level;
                }
            }

            if (userobj.host) return 5;

            return -1;
        }

        public static void LoadAutoLogins()
        {
            login_items.Clear();

            if (!File.Exists(sb0t_winGUI.RunOnceFileUpdater.sbotpath + "data/autologin.xml")) return;

            try
            {
                FileStream f = new FileStream(sb0t_winGUI.RunOnceFileUpdater.sbotpath + "data/autologin.xml", FileMode.Open);
                XmlReader xml = XmlReader.Create(new StreamReader(f));

                xml.MoveToContent();
                xml.ReadSubtree().ReadToFollowing("autologins");

                while (xml.ReadToFollowing("autologin"))
                {
                    AutoLoginItem a = new AutoLoginItem();

                    xml.ReadSubtree().ReadToFollowing("guid");
                    a.guid = new Guid(Convert.FromBase64String(xml.ReadElementContentAsString()));
                    xml.ReadToFollowing("name");

                    String str = xml.ReadElementContentAsString();
                    List<byte> buf = new List<byte>(Convert.FromBase64String(str));

                    if (buf[0] > 0 && buf[0] < 5)
                    {
                        a.level = buf[0];
                        buf.RemoveAt(0);

                    }
                    else
                    {
                        a.level = 4;
                    }

                    a.name = Encoding.UTF8.GetString(buf.ToArray());
                    xml.ReadToFollowing("ip");
                    a.ip = new IPAddress(Convert.FromBase64String(xml.ReadElementContentAsString()));

                    login_items.Add(a);
                }

                xml.Close();
                f.Flush();
                f.Close();
            }
            catch { }
        }

        private static void SaveAutoLogins()
        {
            mutex.WaitOne();

            try
            {
                XmlWriterSettings appearance = new XmlWriterSettings();
                appearance.Indent = true;
                XmlWriter xml = XmlWriter.Create(sb0t_winGUI.RunOnceFileUpdater.sbotpath + "data/autologin.xml", appearance);

                xml.WriteStartDocument();
                xml.WriteStartElement("autologins");

                foreach (AutoLoginItem a in login_items)
                {
                    xml.WriteStartElement("autologin");
                    xml.WriteElementString("guid", Convert.ToBase64String(a.guid.ToByteArray()));
                    List<byte> buf = new List<byte>();
                    buf.Add((byte)a.level);
                    buf.AddRange(Encoding.UTF8.GetBytes(a.name));
                    xml.WriteElementString("name", Convert.ToBase64String(buf.ToArray()));
                    xml.WriteElementString("ip", Convert.ToBase64String(a.ip.GetAddressBytes()));
                    xml.WriteEndElement();
                }

                xml.WriteEndElement();
                xml.WriteEndDocument();
                xml.Flush();
                xml.Close();
            }
            catch { }

            mutex.ReleaseMutex();
        }
    }

    class AutoLoginItem
    {
        public String name;
        public IPAddress ip;
        public Guid guid;
        public int level;
    }
}
